package tools;

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Dimension;


/**
 * Title:
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:
 * @author
 * @version 1.0
 */

public class ProcessFlow extends JPanel {
  private static final int arrowHeadDepth = 8;
  private static final int arrowHeadWidth = 7;

  private JComponent sourceComponent;
  private JComponent destComponent;
  private static final Color fgColor = Color.gray;

  public ProcessFlow() {
//    setBackground( Color.green );
    setOpaque( false );
  }

  public ProcessFlow( JComponent src, JComponent dst ){
    this();
    setSourceComponent( src );
    setDestComponent( dst );
  }

  public JComponent getSourceComponent() {
    return sourceComponent;
  }

  public void setSourceComponent(JComponent sourceComponent) {
    this.sourceComponent = sourceComponent;
  }

  public void setDestComponent(JComponent destComponent) {
    this.destComponent = destComponent;
  }

  public JComponent getDestComponent() {
    return destComponent;
  }

  static public Point2D.Float getComponentCenter( JComponent c ){
    Point ipt = c.getLocationOnScreen();
    Point2D.Float pt = new Point2D.Float( ipt.x, ipt.y );
    pt.x += c.getWidth() / 2.0f;
    pt.y += c.getHeight() / 2.0f;

    return pt;
  }

  protected void paintComponent(Graphics g) {
    super.paintComponent( g );
    Graphics2D g2d = (Graphics2D)g;

    g2d.setColor( fgColor );

    Point2D.Float srcCtr = getComponentCenter( sourceComponent );
    Point2D.Float dstCtr = getComponentCenter( destComponent );
    Point2D.Float myCtr = getComponentCenter( this );
    Point2D.Float ctr = new Point2D.Float( getWidth() / 2.0f, getHeight() / 2.0f );

    Point2D.Float offset = new Point2D.Float( myCtr.x - ctr.x, myCtr.y - ctr.y );
    Line2D.Float srcLn = new Line2D.Float( srcCtr.x - offset.x, srcCtr.y - offset.y, ctr.x, ctr.y );
    Line2D.Float dstLn = new Line2D.Float( ctr.x, ctr.y, dstCtr.x - offset.x, dstCtr.y - offset.y );

    Stroke s = new BasicStroke( 4 /*, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND */ );

    g2d.setStroke( s );
    g2d.draw( srcLn );
//    g2d.draw( dstLn );

    // determine the point at which the dstLn exits this component
    int maxX = getWidth()/* - 1*/;
    int maxY = getHeight()/* - 1*/;
    float y = 0;
    float x = 0;
    GeneralPath arrowHead = new GeneralPath();
    arrowHead.moveTo( ctr.x, ctr.y );
    if ( dstLn.intersectsLine( maxX, 0, maxX, maxY ) ){
      // right side
      x = maxX;
      y = ctr.y;
      arrowHead.lineTo( x - arrowHeadDepth, y );
      arrowHead.moveTo( x, y );
      arrowHead.lineTo( x - arrowHeadDepth, y - arrowHeadWidth );
      arrowHead.lineTo( x - arrowHeadDepth, y + arrowHeadWidth );
      arrowHead.closePath();
    } else if ( dstLn.intersectsLine( 0, 0, 0, maxY ) ){
      // left side
      System.out.print( "left: " );
    } else if ( dstLn.intersectsLine( 0, 0, maxX, 0 ) ){
      // top side
      x = ctr.x;
      y = 0;
      arrowHead.lineTo( x, y + arrowHeadDepth );
      arrowHead.moveTo( x, y );
      arrowHead.lineTo( x - arrowHeadWidth, y + arrowHeadDepth );
      arrowHead.lineTo( x + arrowHeadWidth, y + arrowHeadDepth );
      arrowHead.closePath();
    } else if ( dstLn.intersectsLine( 0, maxY, maxX, maxY ) ){
      // bottom side
      x = ctr.x;
      y = maxY;
      arrowHead.lineTo( x, y - arrowHeadDepth );
      arrowHead.moveTo( x, y );
      arrowHead.lineTo( x - arrowHeadWidth, y - arrowHeadDepth );
      arrowHead.lineTo( x + arrowHeadWidth, y - arrowHeadDepth );
      arrowHead.closePath();
    }
//    g2d.setColor( g2d.getBackground() );
//    Rectangle r = arrowHead.getBounds();
//    g2d.clearRect( r.x, r.y, r.width, r.height );

    g2d.setColor( fgColor );
    g2d.fill( arrowHead );
  }

  public Dimension getPreferredSize() {
    return new Dimension( 20, 20 );
  }
}